<script setup lang="ts">
import type { TreeProps } from 'ant-design-vue';

import { ref, watch } from 'vue';

import { useVbenDrawer } from '@vben/common-ui';

import { message } from 'ant-design-vue';

import { permissionQueryListApi } from '#/api/system/permission';
import { authRoleApi, queryAuthByRoleIdApi } from '#/api/system/role';

const record = ref();
// 提交按钮文本
const confirmText = ref('提交');
// 定义 treeData 作为响应式变量
const treeData = ref<TreeProps['treeData']>([]);
// 角色原先权限
const treeRoleData = ref<string[]>([]);
// 设置选中的节点
const checkedKeys = ref<string[]>([]);
// 是否关联父子节点
const checkStrictly = ref<Boolean>(true);
// 是否展开全部
const defaultStyleAll = ref<Boolean>(false);
// 是否勾选全部
const defaultCheckAll = ref<Boolean>(true);
// 设置展开的节点
const expandedKeys = ref<string[]>([]);

const fieldNames: TreeProps['fieldNames'] = {
  children: 'children',
  title: 'name',
  key: 'id',
};
const [Drawer, drawerApi] = useVbenDrawer({
  title: '角色授权',
  confirmText,
  onConfirm: onSubmit,
  onOpenChange(isOpen: boolean) {
    if (isOpen) {
      record.value = drawerApi.getData<Record<string, any>>();
      drawerApi.setState({ title: `角色授权「${record.value.roleName}」` });
      initFun();
    }
  },
});

watch(checkedKeys, () => {
  let ids;
  if (Array.isArray(checkedKeys.value)) {
    ids = checkedKeys.value;
  } else if (
    typeof checkedKeys.value === 'object' &&
    checkedKeys.value !== null
  ) {
    ids = checkedKeys.value.checked || [];
  }
  confirmText.value = `提交(${ids.length})`;
});

async function initFun() {
  await loadAuthTree();
  await loadRoleAuths();
  changeRadioStyleAll();
}
async function loadAuthTree() {
  treeData.value = await permissionQueryListApi();
}
async function loadRoleAuths() {
  treeRoleData.value = await queryAuthByRoleIdApi({ roleId: record.value.id });
  checkedKeys.value = treeRoleData.value;
}
async function onSubmit() {
  let ids;
  if (Array.isArray(checkedKeys.value)) {
    ids = checkedKeys.value;
  } else if (
    typeof checkedKeys.value === 'object' &&
    checkedKeys.value !== null
  ) {
    ids = checkedKeys.value.checked || [];
  }
  const msg = await authRoleApi({ roleId: record.value.id, authIds: ids });
  message.success(msg);
  drawerApi.close();
}
// 设置展开或折叠
function changeRadioStyleAll() {
  const allKeys = getAllNodeKeys(treeData.value);
  // eslint-disable-next-line unicorn/prefer-ternary
  if (defaultStyleAll.value) {
    // 折叠所有节点
    expandedKeys.value = [];
  } else {
    // 展开所有节点
    expandedKeys.value = allKeys;
  }
}
// 设置勾选全部和取消勾选全部
function changeRadioCheckAll() {
  const allKeys = getAllNodeKeys(treeData.value);
  // eslint-disable-next-line unicorn/prefer-ternary
  if (defaultCheckAll.value) {
    // 清空选中状态
    checkedKeys.value = [];
  } else {
    // 设置所有叶子节点为选中状态
    checkedKeys.value = allKeys;
  }
}
// 收集所有的 key
function getAllNodeKeys(data: TreeProps['treeData']): string[] {
  const keys: string[] = [];
  function traverse(nodes: any[]) {
    nodes.forEach((node) => {
      keys.push(node.id);
      if (node.children) {
        traverse(node.children);
      }
    });
  }
  traverse(data);
  return keys;
}
</script>

<template>
  <Drawer>
    <div>
      <a-radio-group v-model:value="checkStrictly" class="mr-2">
        <a-radio-button :value="false"> 层级关联 </a-radio-button>
        <a-radio-button :value="true"> 层级独立 </a-radio-button>
      </a-radio-group>
      <a-radio-group
        v-model:value="defaultStyleAll"
        class="mr-2"
        @change="changeRadioStyleAll"
      >
        <a-radio-button :value="false"> 展开全部 </a-radio-button>
        <a-radio-button :value="true"> 折叠全部 </a-radio-button>
      </a-radio-group>
      <a-radio-group
        v-model:value="defaultCheckAll"
        class="mr-2"
        @change="changeRadioCheckAll"
      >
        <a-radio-button :value="false"> 选择全部 </a-radio-button>
        <a-radio-button :value="true"> 取消选择 </a-radio-button>
      </a-radio-group>
    </div>
    <div class="h-2"></div>
    <a-tree
      v-model:check-strictly="checkStrictly"
      v-model:checked-keys="checkedKeys"
      v-model:expanded-keys="expandedKeys"
      :field-names="fieldNames"
      :tree-data="treeData"
      checkable
    />
  </Drawer>
</template>
